package com.luo.backend.service;

import com.luo.backend.dto.CreateOrderRequest;
import com.luo.backend.dto.OrderResponse;
import com.luo.backend.entity.*;
import com.luo.backend.repository.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单服务类
 */
@Service
public class OrderService {
    
    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private OrderItemRepository orderItemRepository;
    
    @Autowired
    private FoodRepository foodRepository;
    
    @Autowired
    private MerchantRepository merchantRepository;
    
    @Autowired
    private UserAddressRepository addressRepository;
    
    @Autowired
    private GroupBuyingParticipantRepository participantRepository;
    
    @Autowired
    private GroupBuyingActivityRepository activityRepository;
    
    /**
     * 创建订单
     */
    @Transactional
    public OrderResponse createOrder(Long userId, CreateOrderRequest request) {
        logger.info("用户{}创建订单", userId);
        
        // 验证商家
        Optional<Merchant> merchantOpt = merchantRepository.findById(request.getMerchantId());
        if (!merchantOpt.isPresent()) {
            throw new RuntimeException("商家不存在");
        }
        Merchant merchant = merchantOpt.get();
        
        // 验证地址
        Optional<UserAddress> addressOpt = addressRepository.findByIdAndUserId(request.getAddressId(), userId);
        if (!addressOpt.isPresent()) {
            throw new RuntimeException("收货地址不存在");
        }
        UserAddress address = addressOpt.get();
        
        // 验证商品并计算金额
        List<OrderItem> orderItems = new ArrayList<>();
        BigDecimal foodAmount = BigDecimal.ZERO;
        
        for (CreateOrderRequest.OrderItemRequest itemRequest : request.getItems()) {
            Optional<Food> foodOpt = foodRepository.findById(itemRequest.getFoodId());
            if (!foodOpt.isPresent()) {
                throw new RuntimeException("商品不存在：" + itemRequest.getFoodId());
            }
            
            Food food = foodOpt.get();
            
            // 检查商品是否属于该商家
            if (!food.getMerchantId().equals(request.getMerchantId())) {
                throw new RuntimeException("商品不属于该商家");
            }
            
            // 检查库存
            if (food.getStock() < itemRequest.getQuantity()) {
                throw new RuntimeException("商品库存不足：" + food.getName());
            }
            
            // 计算小计
            BigDecimal subtotal = food.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity()));
            foodAmount = foodAmount.add(subtotal);
            
            // 创建订单商品明细
            OrderItem orderItem = new OrderItem();
            orderItem.setFoodId(food.getId());
            orderItem.setFoodName(food.getName());
            orderItem.setFoodImage(food.getImage());
            orderItem.setFoodPrice(food.getPrice());
            orderItem.setQuantity(itemRequest.getQuantity());
            orderItem.setSpiceLevel(itemRequest.getSpiceLevel());
            orderItem.setSubtotal(subtotal);
            
            orderItems.add(orderItem);
        }
        
        // 计算总金额
        BigDecimal deliveryFee = merchant.getDeliveryFee();
        BigDecimal totalAmount = foodAmount.add(deliveryFee);
        
        // 检查最低消费
        if (foodAmount.compareTo(merchant.getMinOrderAmount()) < 0) {
            throw new RuntimeException("未达到最低消费金额：" + merchant.getMinOrderAmount());
        }
        
        // 生成订单号
        String orderNo = generateOrderNo();
        
        // 创建订单
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setMerchantId(merchant.getId());
        order.setMerchantName(merchant.getName());
        order.setDeliveryAddress(String.format("%s %s %s %s", 
            address.getProvince(), address.getCity(), address.getDistrict(), address.getAddress()));
        order.setDeliveryPhone(address.getPhone());
        order.setDeliveryName(address.getName());
        order.setFoodAmount(foodAmount);
        order.setDeliveryFee(deliveryFee);
        order.setTotalAmount(totalAmount);
        order.setStatus("pending");
        order.setNotes(request.getNotes());
        
        // 设置配送时间
        if (request.getScheduledDeliveryDate() != null) {
            order.setScheduledDeliveryDate(LocalDate.parse(request.getScheduledDeliveryDate()));
        }
        order.setScheduledDeliveryTime(request.getScheduledDeliveryTime());
        
        // 保存订单
        order = orderRepository.save(order);
        
        // 保存订单商品明细
        for (OrderItem item : orderItems) {
            item.setOrderId(order.getId());
        }
        orderItemRepository.saveAll(orderItems);
        
        // ========== 🆕 关联拼单活动 ==========
        if (request.getActivityId() != null) {
            logger.info("订单关联拼单活动: activityId={}", request.getActivityId());
            
            // 查询用户在该拼单活动中的参与记录
            Optional<GroupBuyingParticipant> participantOpt = 
                participantRepository.findByActivityIdAndUserId(request.getActivityId(), userId);
            
            if (participantOpt.isPresent()) {
                GroupBuyingParticipant participant = participantOpt.get();
                // 将订单ID写入参与者记录
                participant.setOrderId(order.getId());
                participantRepository.save(participant);
                logger.info("订单{}已关联到拼单参与记录，订单保持pending状态，等待用户支付", order.getId());
            } else {
                logger.warn("未找到用户{}在拼单活动{}中的参与记录", userId, request.getActivityId());
            }
        }
        // =======================================
        
        // 减少库存
        for (int i = 0; i < request.getItems().size(); i++) {
            CreateOrderRequest.OrderItemRequest itemRequest = request.getItems().get(i);
            Optional<Food> foodOpt = foodRepository.findById(itemRequest.getFoodId());
            if (foodOpt.isPresent()) {
                Food food = foodOpt.get();
                food.setStock(food.getStock() - itemRequest.getQuantity());
                foodRepository.save(food);
            }
        }
        
        logger.info("订单创建成功: {}", orderNo);
        
        // 构建响应
        OrderResponse response = new OrderResponse(order);
        response.setItems(orderItems.stream()
            .map(OrderResponse.OrderItemResponse::new)
            .collect(Collectors.toList()));
        
        return response;
    }
    
    /**
     * 获取用户订单列表
     */
    public Map<String, Object> getUserOrders(Long userId, String status, int page, int limit) {
        logger.info("获取用户{}订单列表: status={}, page={}, limit={}", userId, status, page, limit);
        
        Pageable pageable = PageRequest.of(page - 1, limit);
        Page<Order> orderPage;
        
        if (status != null && !status.trim().isEmpty()) {
            orderPage = orderRepository.findByUserIdAndStatusOrderByCreatedAtDesc(userId, status.trim(), pageable);
        } else {
            orderPage = orderRepository.findByUserIdOrderByCreatedAtDesc(userId, pageable);
        }
        
        // 转换为响应DTO
        List<OrderResponse> orders = orderPage.getContent().stream()
                .map(order -> {
                    OrderResponse response = new OrderResponse(order);
                    // 获取订单商品明细
                    List<OrderItem> items = orderItemRepository.findByOrderIdOrderByCreatedAtAsc(order.getId());
                    response.setItems(items.stream()
                        .map(OrderResponse.OrderItemResponse::new)
                        .collect(Collectors.toList()));
                    return response;
                })
                .collect(Collectors.toList());
        
        // 构建分页信息
        Map<String, Object> pagination = new HashMap<>();
        pagination.put("current_page", page);
        pagination.put("per_page", limit);
        pagination.put("total", orderPage.getTotalElements());
        pagination.put("total_pages", orderPage.getTotalPages());
        
        // 构建响应
        Map<String, Object> result = new HashMap<>();
        result.put("orders", orders);
        result.put("pagination", pagination);
        
        return result;
    }
    
    /**
     * 获取订单详情
     */
    public OrderResponse getOrderById(Long userId, Long orderId) {
        logger.info("获取订单详情: userId={}, orderId={}", userId, orderId);
        
        Optional<Order> orderOpt = orderRepository.findByIdAndUserId(orderId, userId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        Order order = orderOpt.get();
        OrderResponse response = new OrderResponse(order);
        
        // 获取订单商品明细
        List<OrderItem> items = orderItemRepository.findByOrderIdOrderByCreatedAtAsc(order.getId());
        response.setItems(items.stream()
            .map(OrderResponse.OrderItemResponse::new)
            .collect(Collectors.toList()));
        
        return response;
    }
    
    /**
     * 支付订单
     */
    @Transactional
    public OrderResponse payOrder(Long userId, Long orderId) {
        logger.info("支付订单: userId={}, orderId={}", userId, orderId);
        
        Optional<Order> orderOpt = orderRepository.findByIdAndUserId(orderId, userId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        Order order = orderOpt.get();
        
        if (!"pending".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不允许支付");
        }
        
        // 模拟支付成功
        order.setStatus("paid");
        order.setPaidAt(LocalDateTime.now());
        
        order = orderRepository.save(order);
        
        // ✅ 新增：如果是拼单订单，更新参与者状态
        Optional<GroupBuyingParticipant> participantOpt = 
            participantRepository.findByOrderId(orderId);
        if (participantOpt.isPresent()) {
            GroupBuyingParticipant participant = participantOpt.get();
            participant.setStatus("paid");
            participantRepository.save(participant);
            logger.info("拼单参与者状态已更新为 paid - userId: {}, orderId: {}", userId, orderId);
        }
        
        logger.info("订单支付成功: {}", order.getOrderNo());
        return new OrderResponse(order);
    }
    
    /**
     * 取消订单
     */
    @Transactional
    public OrderResponse cancelOrder(Long userId, Long orderId, String reason) {
        logger.info("取消订单: userId={}, orderId={}, reason={}", userId, orderId, reason);
        
        Optional<Order> orderOpt = orderRepository.findByIdAndUserId(orderId, userId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        Order order = orderOpt.get();
        
        if (!"pending".equals(order.getStatus()) && !"paid".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不允许取消");
        }
        
        // 保存原始状态用于判断
        String originalStatus = order.getStatus();
        
        order.setStatus("cancelled");
        order.setCancelReason(reason);
        order.setCancelledAt(LocalDateTime.now());
        
        // 如果已支付，同时设置退款时间
        if ("paid".equals(originalStatus)) {
            order.setRefundedAt(LocalDateTime.now());
        }
        
        order = orderRepository.save(order);
        
        logger.info("订单取消成功: {}", order.getOrderNo());
        return new OrderResponse(order);
    }
    
    /**
     * 申请退款
     */
    @Transactional
    public OrderResponse refundOrder(Long userId, Long orderId, String reason) {
        logger.info("申请退款: userId={}, orderId={}, reason={}", userId, orderId, reason);
        
        Optional<Order> orderOpt = orderRepository.findByIdAndUserId(orderId, userId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        Order order = orderOpt.get();
        
        if (!"paid".equals(order.getStatus())) {
            throw new RuntimeException("订单未支付，无法申请退款");
        }
        
        order.setStatus("refunded");
        order.setRefundReason(reason);
        order.setRefundedAt(LocalDateTime.now());
        
        order = orderRepository.save(order);
        
        logger.info("退款申请成功: {}", order.getOrderNo());
        return new OrderResponse(order);
    }
    
    /**
     * 确认收货
     */
    @Transactional
    public OrderResponse confirmReceipt(Long userId, Long orderId) {
        logger.info("确认收货: userId={}, orderId={}", userId, orderId);
        
        // 1. 查询订单
        Optional<Order> orderOpt = orderRepository.findByIdAndUserId(orderId, userId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        Order order = orderOpt.get();
        
        // 2. 权限校验：只能确认自己的订单
        if (!order.getUserId().equals(userId)) {
            logger.warn("权限校验失败 - 订单ID: {}, 订单用户: {}, 当前用户: {}", 
                     orderId, order.getUserId(), userId);
            throw new RuntimeException("无权操作此订单");
        }
        
        // 3. 状态校验：只有配送中或已送达的订单才能确认收货
        String status = order.getStatus();
        if (!"shipping".equals(status) && !"delivered".equals(status)) {
            logger.warn("状态校验失败 - 订单ID: {}, 当前状态: {}", orderId, status);
            throw new RuntimeException("当前订单状态无法确认收货");
        }
        
        // 4. 重复确认检查
        if (order.getConfirmedAt() != null) {
            logger.warn("订单已确认收货 - 订单ID: {}, 确认时间: {}", 
                     orderId, order.getConfirmedAt());
            throw new RuntimeException("订单已确认收货，请勿重复操作");
        }
        
        // 5. 更新订单状态
        order.setStatus("delivered");  // 状态保持为已送达
        order.setConfirmedAt(LocalDateTime.now());  // ⭐ 设置确认收货时间
        order.setIsAutoConfirmed(0);  // 用户手动确认
        order.setUpdatedAt(LocalDateTime.now());
        
        // 6. 保存到数据库
        order = orderRepository.save(order);
        
        logger.info("✅ 确认收货成功 - 订单ID: {}, 用户ID: {}, 确认时间: {}", 
                 orderId, userId, order.getConfirmedAt());
        
        // 7. 构建响应
        OrderResponse response = new OrderResponse(order);
        
        // 获取订单商品明细
        List<OrderItem> items = orderItemRepository.findByOrderIdOrderByCreatedAtAsc(order.getId());
        response.setItems(items.stream()
            .map(OrderResponse.OrderItemResponse::new)
            .collect(Collectors.toList()));
        
        return response;
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        String prefix = "ORD";
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.format("%04d", new Random().nextInt(10000));
        String orderNo = prefix + timestamp + random;
        
        // 确保订单号唯一
        while (orderRepository.existsByOrderNo(orderNo)) {
            random = String.format("%04d", new Random().nextInt(10000));
            orderNo = prefix + timestamp + random;
        }
        
        return orderNo;
    }
}
